#pragma once

#include "../adapter/adapter.h"
#include "interface.h"

class jtag_tap : private interface_jtag
{
public:
    jtag_tap();

public:
    void bind(openocd::adapter *ad);
    int init(void);
    void add_ir_scan(struct scan_field *in_fields, tap_state_t state);
    void add_ir_scan_noverify(const struct scan_field *in_fields, tap_state_t state);
    void add_dr_scan(int in_num_fields, const struct scan_field *in_fields, tap_state_t state);
    int execute_queue(void);
    void set_error(int error);
    void add_reset(int req_tlr_or_trst, int srst);
    void add_sleep(uint32_t us);
    void add_plain_dr_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, tap_state_t state);
    void add_tlr(void);

    int jtag_init_inner();
    void jtag_add_runtest(int num_cycles, tap_state_t state);
    int reset();

public:
    uint32_t idCode(bool refresh = false);

private:
    void jtag_checks(void);
    void jtag_prelude(tap_state_t state);
    int jtag_examine_chain_execute(uint8_t *idcode_buffer, unsigned num_idcode);
    void chain_display(uint32_t idcode);

private:
    bool jtag_verify;
    bool jtag_verify_capture_ir;
    int jtag_trst;
    int jtag_srst;
    int jtag_error;
    tap_state_t cmd_queue_cur_state;
    openocd::adapter *_adapter;
    uint8_t expected[8];
    uint8_t expected_mask[8];
    int jtag_ntrst_assert_width;
    int jtag_ntrst_delay;
    uint32_t _idcode;
    uint32_t jtag_reset_config;
    uint16_t adapter_nsrst_delay;
    uint16_t adapter_nsrst_assert_width;
};
